package org.paybiz.core.payplatform.bill99.util;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.paybiz.core.payplatform.bill99.constant.Bill99Constant;

/**
 * 快钱支付签名类
 * @author nassir wen
 * @data 2012-5-12 下午05:43:02
 * @version V2.5
 * @Company: MSD.
 * @Copyright Copyright (c) 2012
 */
public class Pkipair {
	
    private static final Log logger = LogFactory.getLog(Pkipair.class);
	/**
	 * 数据签名
	 * @param signMsg
	 * @return
	 */
	public static String signMsg( String signMsg) {

		String base64 = "";
		try {
			// 密钥仓库
			KeyStore ks = KeyStore.getInstance("PKCS12");

			// 读取密钥仓库
//			FileInputStream ksfis = new FileInputStream("e:/tester-rsa.pfx");
			
			// 读取密钥仓库（相对路径）
			String file = Bill99Constant.BILL99_PFX_PATH;
			
			FileInputStream ksfis = new FileInputStream(file);
			
			BufferedInputStream ksbufin = new BufferedInputStream(ksfis);

			char[] keyPwd = Bill99Constant.BILL99_PASSWD.toCharArray();
			ks.load(ksbufin, keyPwd);
			// 从密钥仓库得到私钥
			PrivateKey priK = (PrivateKey) ks.getKey("test-alias", keyPwd);
			Signature signature = Signature.getInstance("SHA1withRSA");
			signature.initSign(priK);
			signature.update(signMsg.getBytes("utf-8"));
			sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
			base64 = encoder.encode(signature.sign());
		} catch(FileNotFoundException e){
		    logger.error("文件找不到",e);
		}catch (Exception ex) {
			ex.printStackTrace();
			logger.error(ex);
		}
		return base64;
	}
	
	/**
	 * 支付结果签名验证
	 * @param val
	 * @param msg
	 * @return
	 */
	public static boolean enCodeByCer( String val, String msg) {
	    logger.info("sign val: " + val);
		boolean flag = false;
		try {
			//获得文件(绝对路径)
			//InputStream inStream = new FileInputStream("e:/99bill[1].cert.rsa.20140803.cer");
			
			//获得文件(相对路径)
			String file = Bill99Constant.BILL99_CER_PATH;
			FileInputStream inStream = new FileInputStream(file);
			
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
			//获得公钥
			PublicKey pk = cert.getPublicKey();
			//签名
			Signature signature = Signature.getInstance("SHA1withRSA");
			signature.initVerify(pk);
			signature.update(val.getBytes());
			//解码
			sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
			flag = signature.verify(decoder.decodeBuffer(msg));
		} catch (Exception e) {
		    logger.error("支付结果签名验证异常",e);
		} 
		return flag;
	}
	
	/**
     * 获取需签名字符串
     * @param params
     * @return
     */
    public static String getSignMsgVal(Map<String,String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        StringBuilder signMsgVal = new StringBuilder(200);
        for (int i = 0; i < keys.size(); i++) {
            String key = (String) keys.get(i);
            String value = (String) params.get(key);
            if(StringUtils.isNotEmpty(value)) {
                if (signMsgVal.length() > 0) {
                    signMsgVal.append("&").append(key).append("=").append(value);
                } else {
                    signMsgVal.append(key).append("=").append(value);
                }
            }
        }
        return signMsgVal.toString();
    }
    
    public static void main(String[] args) {
        String sign = "v4YXPNJyZm/cKMF1ehJfpAJ8kgKSFtYRKkKdFCNMNBhnKUvEhTPDfEBsymCeIIz7aSTwv8N/SP1pMEBlOXzaIZpbMH6cOVqAl4yflq7ih4kWJ5MpF7EW9C8GQOFbmsPVnj+lsVYONz9uJdJN6qfmfwMaPb034ToXr/eic3fwzIQ=";
        String val = "merchantAcctId=1001181534101&version=v2.0&language=1&signType=4&payType=10&orderId=201205170000000007&orderTime=20120517180505&orderAmount=1&dealId=19634939&bankDealId=120517444855&dealTime=20120517101441&payAmount=1&fee=0&ext1=http://test2.365car.com.cn:81/ics/payCenter/payCenter_payCallBack.action&username=aaaaaa&aaaa=cccc&payResult=10";
        boolean b = Pkipair.enCodeByCer(val, sign);
        System.out.println("签名验证：" + b);
    }
}
